//
//  CreateCarView.swift
//  Automobile
//
//  Created by erkebulan elzhan on 7/28/20.
//  Copyright © 2020 erkebulan elzhan. All rights reserved.
//

import UIKit
import SnapKit


class NumberTextField: UITextField {
    var maxLength: Int!
}


protocol CreateCarProtocol {
    func didErrorHappen (title: String, message: String)
    func didCreateCar(car: Car)
    func hideCreateCarView()
}

final class CreateCarView: UIView {
    
    // MARK: - Outlets
    
    lazy private var cancelBtn: UIButton = {
        let btn = UIButton()
        btn.setImage(UIImage(named: "cancel"), for: .normal)
        return btn
    }()
    lazy private var nameTF: UITextField = {
        let field = UITextField()
        field.textAlignment = .left
        field.font = UIFont.systemFont(ofSize: 20, weight: .medium)
        field.textColor = .rgb(44, 62, 80)
        field.placeholder = "Название авто"
        field.delegate = parent
        return field
    }()
    lazy private var numberHint: UILabel = {
        let label = UILabel()
        label.font = UIFont.systemFont(ofSize: 17, weight: .regular)
        label.textColor = .greyColor
        label.textAlignment = .left
        label.text = "Госномер авто"
        label.sizeToFit()
        return label
    }()
    
    lazy private var carTypeHint: UILabel = {
        let label = UILabel()
        label.font = UIFont.systemFont(ofSize: 17, weight: .regular)
        label.textColor = .greyColor
        label.textAlignment = .left
        label.text = "Тип машины"
        label.sizeToFit()
        return label
    }()
    
    lazy private var carTypeSegmented: RoundedSCView = {
        let segmented = RoundedSCView()
        segmented.updateItems(items: TransportType.allCases.map { $0.rawValue })
        return segmented
    }()
    
        /// Car Government Number View
    lazy private var numberView: UIView = {
        let view = UIView()
        view.clipsToBounds = true
        view.layer.borderWidth = 2
        view.layer.borderColor = UIColor.mediumDarkBlue.cgColor
        view.layer.cornerRadius = 5
        return view
    }()
    lazy private var numbersField: NumberTextField = {
        let field = NumberTextField()
        field.keyboardType = .numberPad
        field.textColor = .greyColor
        field.font = UIFont.systemFont(ofSize: 35, weight: .bold)
        field.maxLength = 3
        field.autocapitalizationType = .allCharacters
        field.addTarget(self, action: #selector(fieldTextChanged(textField:)), for: .editingChanged)
        field.delegate = parent
        return field
    }()
    lazy private var lettersField: NumberTextField = {
        let field = NumberTextField()
        field.keyboardType = .alphabet
        field.textColor = .greyColor
        field.autocapitalizationType = .allCharacters
        field.font = UIFont.systemFont(ofSize: 35, weight: .bold)
        field.maxLength = 3
        field.addTarget(self, action: #selector(fieldTextChanged(textField:)), for: .editingChanged)
        field.delegate = parent
        return field
    }()
    lazy private var cityIdField: NumberTextField = {
        let field = NumberTextField()
        field.autocapitalizationType = .allCharacters
        field.keyboardType = .numberPad
        field.textColor = .greyColor
        field.font = UIFont.systemFont(ofSize: 35, weight: .bold)
        field.maxLength = 2
        field.addTarget(self, action: #selector(fieldTextChanged(textField:)), for: .editingChanged)
        field.delegate = parent
        return field
    }()
    lazy private var dividerView: UIView = {
        let view = UIView()
        view.backgroundColor = .greyColor
        return view
    }()
    
    private lazy var submitButton: UIButton = {
        let btn = UIButton()
        btn.backgroundColor = .blueColor
        btn.setTitle("Добавить", for: .normal)
        btn.clipsToBounds = true
        btn.layer.cornerRadius = 15
        return btn
    }()
    
    private lazy var modeSwitcherBtn: UIButton = {
        let btn = UIButton()
        btn.setTitle("Сменить формат", for: .normal)
        btn.titleLabel?.font = UIFont.systemFont(ofSize: 17, weight: .medium)
        btn.setTitleColor(.blueColor, for: .normal)
        return btn
    }()
    
    // MARK: - Propeties
    
    private var isNew: Bool = false {
        didSet {
            _ = self.numberView.subviews.map {
                $0.removeFromSuperview()
                $0.snp.removeConstraints()
            }
            
            self.addCarNumberView(isNew: isNew)
        }
    }
    var delegate: CreateCarProtocol!
    
    weak var parent: SelectCarViewController!
    
    // MARK: - UI Actions
    
    @objc private func toggleFormat(sender: UIButton) {
        self.isNew = !self.isNew
    }
    @objc private func onTap (sender: UITapGestureRecognizer) {
        for tf in [nameTF, numbersField, lettersField, cityIdField] {
            tf.resignFirstResponder()
        }
    }
    
    @objc private func onReady (sender: UIButton) {
        if (nameTF.text == "") {
            delegate.didErrorHappen(title: "Введите название", message: "Марка машины не должно оставаться пустым")
        } else {
            let isOk = self.checkTextFields()
            if (isOk) {
                delegate.didCreateCar(car: self.createCar())
            } else {
                delegate.didErrorHappen(title: "Упс...", message: "Проверьте все поля")
            }
        }
    }
    
    @objc private func hideView (sender: UIButton) {
        delegate.hideCreateCarView()
    }
    
    // MARK: - Methods
    
    private func checkTextFields () -> Bool {
        var isOk = true
        for tf in [numbersField, lettersField, cityIdField] {
            if (tf.maxLength != tf.text?.count) {
                isOk = false
            }
        }
        return isOk
    }
    
    private func createCar () -> Car {
        let carNumber = CarNumber(isNewFormat: true, number: Int(numbersField.text!) ?? 111, letters: lettersField.text!, cityId: cityIdField.text!)
        let carType = TransportType.allCases[carTypeSegmented.transportSelect.selectedSegmentIndex]
        return Car(id: 2, carNumber: carNumber,
                   carName: nameTF.text,
                   carType: IdAndName(id: TransportType.getId(carType),
                                      ext: TransportType.getExt(carType),
                                      name: carType.rawValue))
    }
    
    
    // MARK: - Init
    
    init () {
        super.init(frame: .zero)
        self.addViews()
        self.backgroundColor = .white
        
        self.layer.shadowOffset = CGSize(width: 0, height: -20)
        self.layer.shadowColor = UIColor.black.cgColor
        self.layer.shadowRadius = 30
        self.layer.shadowOpacity = 0.15
        
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(notification:)), name: UIResponder.keyboardWillHideNotification, object: nil)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    deinit {
        NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil)
        NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
    }
    
    // MARK: Handling Keyboard
    
    @objc private func keyboardWillShow(notification: NSNotification) {
        if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
            self.transform = CGAffineTransform(translationX: 0, y: -keyboardSize.height + 54)
        }
    }

    @objc private func keyboardWillHide(notification: NSNotification) {
        self.transform = .identity
    }
}


extension CreateCarView {
    
    private func addViews () {
        self.addSubview(cancelBtn)
        self.addSubview(carTypeHint)
        self.addSubview(carTypeSegmented)
        self.addSubview(nameTF)
        self.addSubview(numberHint)
        self.addSubview(numberView)
        self.addSubview(submitButton)
        self.addSubview(modeSwitcherBtn)
        
        cancelBtn.addTarget(self, action: #selector(hideView(sender:)), for: .touchUpInside)
        modeSwitcherBtn.addTarget(self, action: #selector(toggleFormat(sender:)), for: .touchUpInside)
        submitButton.addTarget(self, action: #selector(onReady(sender:)), for: .touchUpInside)
        self.addConstraints()
        self.addCarNumberView(isNew: isNew)
    }
    
    private func addConstraints () {
        cancelBtn.snp.makeConstraints { (make) in
            make.width.equalTo(12)
            make.height.equalTo(20)
            make.leading.equalToSuperview().offset(24)
            make.top.equalToSuperview().offset(27)
        }
        modeSwitcherBtn.snp.makeConstraints { (make) in
            make.trailing.equalToSuperview().offset(-16)
            make.centerY.equalTo(cancelBtn.snp.centerY)
            make.height.equalTo(22)
            make.width.equalTo(150)
        }
        nameTF.snp.makeConstraints { (make) in
            make.top.equalTo(cancelBtn.snp.bottom).offset(24)
            make.leading.trailing.equalToSuperview().inset(16)
            make.height.equalTo(24)
        }
        
        carTypeHint.snp.makeConstraints { (make) in
            make.leading.trailing.equalToSuperview().inset(16)
            make.top.equalTo(nameTF.snp.bottom).offset(8)
            make.height.equalTo(20)
        }
        
        carTypeSegmented.snp.makeConstraints { (make) in
            make.height.equalTo(40)
            make.leading.trailing.equalToSuperview().inset(16)
            make.top.equalTo(carTypeHint.snp.bottom).offset(8)
        }
        
        numberHint.snp.makeConstraints { (make) in
            make.leading.trailing.equalToSuperview().inset(16)
            make.top.equalTo(carTypeSegmented.snp.bottom).offset(12)
            make.height.equalTo(20)
        }
        
        numberView.snp.makeConstraints { (make) in
            make.leading.trailing.equalToSuperview().inset(16)
            make.height.equalTo(60)
            make.top.equalTo(numberHint.snp.bottom).offset(8)
        }
        
        submitButton.snp.makeConstraints { (make) in
            make.height.equalTo(44)
            make.leading.trailing.equalToSuperview().inset(16)
            make.bottom.equalToSuperview().offset(-20)
        }
    }
    
    // MARK: - Number View Mode
    
    private func addCarNumberView (isNew: Bool = true) {
        self.numberView.addSubview(numbersField)
        self.numberView.addSubview(lettersField)
        self.numberView.addSubview(cityIdField)
        
        numbersField.delegate = self
        lettersField.delegate = self
        cityIdField.delegate = self
        
        if (isNew) {
            self.makeNewFormatTF()
        } else {
            self.makeOldFormatTF()
        }
    }
    
        /// New Format
    private func makeNewFormatTF () {
        self.numberView.addSubview(dividerView)
        numbersField.placeholder = "111"
        numbersField.textAlignment = .left
        lettersField.placeholder = "AAA"
        lettersField.textAlignment = .center
        cityIdField.placeholder = "00"
        cityIdField.textAlignment = .right
        cityIdField.maxLength = 2
        
        cityIdField.snp.makeConstraints { (make) in
            make.trailing.equalTo(-16)
            make.top.bottom.equalToSuperview().inset(9)
            make.width.equalTo(50)
        }
        dividerView.snp.makeConstraints { (make) in
            make.height.equalToSuperview()
            make.width.equalTo(2)
            make.trailing.equalTo(cityIdField.snp.leading).offset(-16)
            make.centerY.equalToSuperview()
        }
        lettersField.snp.makeConstraints { (make) in
            make.centerY.centerX.equalToSuperview()
            make.top.bottom.equalToSuperview().inset(9)
            make.width.equalTo(80)
        }
        numbersField.snp.makeConstraints { (make) in
            make.leading.equalToSuperview().offset(16)
            make.top.bottom.equalToSuperview().inset(9)
            make.width.equalTo(80)
        }
    }
        /// Old options
    private func makeOldFormatTF () {
        numbersField.placeholder = "111"
        lettersField.placeholder = "AAA"
        cityIdField.placeholder = "A"
        cityIdField.keyboardType = .alphabet
        cityIdField.maxLength = 1
        
        cityIdField.snp.makeConstraints { (make) in
            make.leading.equalToSuperview().offset(16)
            make.top.bottom.equalToSuperview().inset(9)
            make.width.equalTo(30)
        }
        numbersField.snp.makeConstraints { (make) in
            make.centerX.centerY.equalToSuperview()
            make.top.bottom.equalToSuperview().inset(9)
            make.width.equalTo(85)
        }
        lettersField.snp.makeConstraints { (make) in
            make.trailing.equalToSuperview().offset(-16)
            make.top.bottom.equalToSuperview().inset(9)
            make.width.equalTo(85)
        }
    }
}


// MARK: - Text Field

extension CreateCarView: UITextFieldDelegate {
    
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        if (textField is NumberTextField) {
            let tf = textField as! NumberTextField
            let maxLength = tf.maxLength
            let currentString: NSString = textField.text! as NSString
            let newString: NSString =
                currentString.replacingCharacters(in: range, with: string) as NSString
            return newString.length <= maxLength!
        } else {
            return false
        }
    }
    
    @objc private func fieldTextChanged (textField: UITextField) {
        if (textField is NumberTextField) {
            let tf = textField as! NumberTextField
            let maxLength = tf.maxLength
            if (textField.text?.count == maxLength) {
                self.focusTextFields(textField: textField)
            }
        }
    }
    
    
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        return true
    }
    
    private func focusTextFields (textField: UITextField) {
        if isNew {
            if textField == numbersField {
                lettersField.becomeFirstResponder()
            } else if textField == lettersField {
                cityIdField.becomeFirstResponder()
            } else {
                textField.resignFirstResponder()
            }
        } else {
            if cityIdField == textField {
                numbersField.becomeFirstResponder()
            } else if textField == numbersField {
                lettersField.becomeFirstResponder()
            } else {
                textField.resignFirstResponder()
            }
        }
    }
    
}
